﻿using System;
using System.Collections.Generic;
using System.Linq;
using Atmk.WaterMeter.MIS.Base;
using Atmk.WaterMeter.MIS.Common;
using Atmk.WaterMeter.MIS.Commons.Interfaces.Logic;
using Atmk.WaterMeter.MIS.Commons.Interfaces.Logic.Statistics;
using Atmk.WaterMeter.MIS.Commons.ViewModels.District;
using Atmk.WaterMeter.MIS.Datas;
using Atmk.WaterMeter.MIS.Entities.Enums;
using Atmk.WaterMeter.MIS.Entities.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace Atmk.WaterMeter.MIS.Controllers
{
    /// <summary>
    ///     片区信息管理
    /// </summary>
    [Authorize]
    public class DistrictsController : BaseApiController
    {
        private static ILogger<DistrictsController> _logger;
        private readonly IBaseInfoLogic _baseStatistcsLogic;
        private readonly IProjectsLogic _projectsLogic;
        private readonly IDistrictLogic _districtLogic;
        private readonly IOwnerMeterLogic _ownersLogic;
        private readonly ISelectCoordinatesLogic _selectCoordinatesLogic;
        private readonly IStaffLogic _staffLogic;
        private readonly TokenHelper _tokenHelper;

        /// <inheritdoc />
        public DistrictsController(ILogger<DistrictsController> logger,
            IBaseInfoLogic baseStatistcsLogic,
            IDistrictLogic districtLogic,
            IProjectsLogic projectsLogic,
            IOwnerMeterLogic ownersLogic,
            ISelectCoordinatesLogic selectCoordinatesLogic,
            IStaffLogic staffLogic,
            TokenHelper tokenHelper)
        {
            _logger = logger;
            _tokenHelper = tokenHelper;
            _baseStatistcsLogic = baseStatistcsLogic;
            _projectsLogic = projectsLogic;
            _districtLogic = districtLogic;
            _ownersLogic = ownersLogic;
            _staffLogic = staffLogic;
            _selectCoordinatesLogic = selectCoordinatesLogic;
        }

        /// <summary>
        ///     获取项目、片区、业主所有节点信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Nodes()
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息

            //根据用户获取片区编码集合
            try
            {
                var uid = token.payload.id;
                var areaId = new Guid(token.payload.areaid);
                //获取项目
                var project = _projectsLogic.GetProject(areaId);
                //获取片区信息集合
                var districts = _districtLogic.GetDistricts(areaId).OrderByDescending(m=>m.CreateTime);
                //获取操作员的片区排序信息集合
                var sequences = _districtLogic.GetDistrictOrder(uid);
                //获取该片区集合下，所有业主信息的集合
                var owner = _ownersLogic.GetOwner(districts.Select(d => d.Id).ToArray());
                //组装
                var list = new List<DistrictNode>();
                list.Add(new DistrictNode
                {
                    id = project.Id,
                    name = project.Name,
                    parentId = "0", //项目没有父级
                    nodeType = TreeNodeType.root.ToString(),
                    displayOrder = 0 //项目不读取排序
                });
                list.AddRange(districts.Select(d => new DistrictNode
                {
                    id = d.Id,
                    name = d.Name,
                    parentId = string.IsNullOrEmpty(d.Parent.Trim()) ? project.Id.ToString() : d.Parent,
                    nodeType = d.NodeType.ToString(),
                    displayOrder = GetDistplayOrder(sequences, uid, d.Id)
                }).ToList());
                list.AddRange(owner.Select(d => new DistrictNode
                {
                    id = d.Id,
                    name = d.Name,
                    parentId = d.DistrictId,
                    //nodeType = TreeNodeType.leaf.ToString(),
                    nodeType = Convert.ToString((int)TreeNodeType.leaf),
                    displayOrder = 0 //业主不读取排序
                }).OrderBy(n => n.name).ToList());
                var result = new DistrictNodesResult
                {
                    errcode = 0,
                    msg = "ok",
                    data = new DistrictNodesData {areaList = list}
                };
                //反馈结果
                return Ok(result);
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message, e);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取片区数据错误,错误:{e.Message}"
                });
            }
        }

        /// <summary>
        /// 获取片区排序序号
        /// </summary>
        /// <param name="sequences"></param>
        /// <param name="uid"></param>
        /// <param name="districtId"></param>
        /// <returns></returns>
        private int GetDistplayOrder(List<DistrictSequences> sequences, string uid, string districtId)
        {
            var order = 0;
            var nullSequence = sequences.FirstOrDefault(s => s.StaffId == uid && s.DistrictId == districtId)
                ?.DisplaySequence;
            if (nullSequence != null)
                order = nullSequence.Value;
            return order;
        }

        /// <summary>
        ///     查询片区详细信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("{districtId}")]
        public IActionResult Nodes(string districtId)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息

            //获取配置
            var pageSize = _baseStatistcsLogic.PageSize(token.payload.id);

            var districtGuid = new Guid(districtId);

            try
            {
                District district;
                try
                {
                    //获取片区信息
                    district = _districtLogic.GetDistrict(districtGuid);
                }
                catch (ArgumentNullException e)
                {
                    _logger.LogError(e.Message, e);
                    return Ok(new
                    {
                        errcode = 1,
                        msg = $"片区源获取为空值"
                    });
                }
                catch (InvalidOperationException e)
                {
                    _logger.LogError(e.Message, e);
                    return Ok(new
                    {
                        //errcode = 1,
                        //msg = $"找不到片区集合"
                        errcode = 0,
                        msg = "ok",
                        data =new DistrictInformationData()
                    });
                }
                //获取坐标信息
                var coordinate = _selectCoordinatesLogic.GetCoordinate(district.Id);
                //组合
                var data = new DistrictInformationData
                {
                    districtId = district.Id,
                    districtName = district.Name,
                    elevation = "0",
                    coordinates = coordinate,
                    remark = district.Memo

                };
                var result = new DistrictInformationResult
                {
                    errcode = 0,
                    msg = "ok",
                    data = data
                };
                return Ok(result);
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message, e);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取片区数据错误,错误:{e.Message}"
                });
            }
        }

        /// <summary>
        /// 片区显示顺序修改
        /// </summary>
        /// <param name="objBody"></param>
        /// <returns></returns>
        [HttpPut]
        public IActionResult Reorder([FromBody] DistrictNodeSequencesBody objBody)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            try
            {
                var res = _districtLogic.UpdateSequences(objBody.list.ToArray());
                return Ok(res
                    ? new {errcode = 0, msg = "ok"}
                    : new {errcode = 1, msg = $"修改片区顺序失败"});
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message, e);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"修改片区顺序失败:{e.Message}"
                });
            }
        }

        /// <summary>
        ///     添加片区信息
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult InsertDistricts([FromBody] DistrictInfomationBody obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            var uid = token.payload.id;
            //验证用户信息

            if (obj == null)
            {
                _logger.LogDebug("获取参数为空值");
                return Ok(new
                {
                    errcode = 1,
                    msg = "接收参数是空值"
                });
            }

            try
            {
                var res = _districtLogic.InsertDistrict(obj, uid, out var districtId);
                return Ok(res
                    ? new {errcode = 0, msg = "ok", id = districtId}
                    : new
                    {
                        errcode = 1,
                        msg = "添加片区失败",
                        id = ""
                    });
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message, e);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"添加片区失败\r\n{e.Message}"
                });
            }
        }

        /// <summary>
        ///     修改片区信息
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UpdateDistricts([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息
            try
            {
                var res = _districtLogic.UpadateDistrict(obj, out Exception exception);
                return Ok(res
                    ? new {errcode = 0, msg = "ok"}
                    : new {errcode = 1, msg = $"修改片区错误,错误:{exception.Message}"});
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message, e);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"修改片区错误:{e.Message}"
                });
            }
        }

        /// <summary>
        ///     删除片区信息
        /// </summary>
        /// <param name="districtId"></param>
        /// <returns></returns>
        [HttpDelete("{districtId}")]
        public IActionResult DeletDistricts(string districtId)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息
            try
            {
                var gid = districtId;
                var uid = token.payload.id;
                var res = _districtLogic.DeleteDistrict(gid, uid, out Exception exception);
                if (!res)
                    _logger.LogError(exception.Message, exception);
                return Ok(res
                    ? new {errcode = 0, msg = "ok"}
                    : new {errcode = 1, msg = $"删除片区错误,错误:{exception.Message}"});
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message, e);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"删除片区错误:{e.Message}"
                });
            }
        }

        [HttpPost("/api/{X-Version}/[controller]/transferDistrict")]
        public IActionResult transferDistrict([FromBody]dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息
            Newtonsoft.Json.Linq.JArray ownerids = obj.ownerids;
            string Districtid = obj.Districtid;
            List<string> arr_ids=new List<string>();
            foreach (string item in ownerids)
            {
                arr_ids.Add(item);
            }

            //根据用户获取片区编码集合进行匹配
            try
            {
                using (var _context = ContextBuilder.Build())
                {
                    var Owners = _context.Owner.Where(m => arr_ids.Contains(m.Id)).ToList();
                    foreach (var item in Owners)
                    {
                        item.DistrictId = Districtid;
                    }
                    _context.Owner.UpdateRange(Owners);

                    var meters = _context.Meter.Where(m => Owners.Select(m1=>m1.Id).Contains(m.OwnerId)).ToList();
                    foreach (var item in meters)
                    {
                        item.DistrictId = Districtid;
                    }
                    _context.Meter.UpdateRange(meters);
                    int r = _context.SaveChanges();
                    return Ok(new
                    {
                        errcode = 0,
                        msg = "ok",
                        result = r
                    });
                }
            }
            catch (Exception e)
            {
                //_logger.Error(e.Message);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取数据错误,错误:{e.Message}"
                });
            }
        }

    }
}